Skip to main content

Json 反编译的坑

转换数字类型的时候

postId, _ := jsonPost["id"].(json.Number).Int64()

转换数组

jsonPost := post0.(map[string]interface{})

转换字符串

jsonPost["body"].(string),

项目中的封装

// Package internal .
// 版权所有[成都尼毕鲁科技股份有限公司]
// 根据《保密信息使用许可证》获得许可;
// 除非符合许可,否则您不得使用此文件。
// 您可以在以下位置获取许可证副本,链接地址:
// https://wiki.tap4fun.com/pages/viewpage.action?pageId=29818250
// 除非适用法律要求或书面同意,否则保密信息按照使用许可证要求使用,不附带任何明示或暗示的保证或条件。
// 有关管理权限的特定语言,请参阅许可证副本。
package internal

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"

"git.tap4fun.com/fw/tse/core/util/idgen"

"git.tap4fun.com/fw/tse/core/util"
"github.com/sirupsen/logrus"
)

// Args 参数表
type Args map[string]string

// Args force send in QueryString
var forceQueryArgs = []string{"client_id"}

// request 阻塞的请求调用,错误调用方处理
func (pfc *pfclientdef) request(service, path, method string, args Args) (map[string]interface{}, error) {
return pfc.request2(service, path, method, args, defaultRetryTimes)
}

// request2 请求
func (pfc *pfclientdef) request2(service, path, method string, args Args, retry int) (map[string]interface{}, error) {
reqID := idgen.NewID()
baseURL := pfc.GetServiceURL(service)
if baseURL == "" {
err := fmt.Errorf("pf: can not found service %v url", service)
return nil, err
}
var resp *http.Response
var err error
for {
retry--
resp, err = pfc.doRequest(baseURL, path, method, args)
if err != nil && retry > 0 {
pfc.addError()
logrus.Errorf("pf http request[%d]: %s, %s, %v failed: %v, retry", reqID, method, baseURL+"/"+path, args, err)
continue
} else if err != nil {
pfc.addError()
logrus.Errorf("pf http request[%d]: %s, %s, %v failed: %v, finally", reqID, method, baseURL+"/"+path, args, err)
break
}
break
}
if err != nil {
return nil, err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
logrus.Errorf("pf http request[%d]: %s, %s, %v failed: read body error: %v", reqID, method, baseURL+"/"+path, args, err)
return nil, err
}
logrus.Debugf("pf http request[%d], %s, %s, %v, resp: %v", reqID, method, baseURL+"/"+path, args, string(data))
var jsonmap map[string]interface{}
decoder := json.NewDecoder(bytes.NewReader(data))
decoder.UseNumber()
err = decoder.Decode(&jsonmap)
if err != nil {
return nil, err
}
// 检查平台通用错误码
err = checkError(jsonmap)
return jsonmap, err
}

// doRequest 发送http request
func (pfc *pfclientdef) doRequest(baseURL, path, method string, args Args) (*http.Response, error) {
startTimestamp := util.NowTs()
var req *http.Request
var err error

// 应平台要求,如果请求没带client_id参数,添加之
if args == nil {
args = map[string]string{"client_id": pfc.ClientID}
} else if _, ok := args["client_id"]; !ok {
args["client_id"] = pfc.ClientID
}

switch method {
case http.MethodPost:
var body io.Reader
queryArgs := url.Values{}

if args != nil {
data := argsToURLValues(args)
for _, arg := range forceQueryArgs {
if val := data.Get(arg); val != "" {
queryArgs.Set(arg, val)
data.Del(arg)
}
}

body = strings.NewReader(data.Encode())
}
urlquery := makeURLQuery(baseURL, path, queryArgs.Encode())
if req, err = http.NewRequest(method, urlquery, body); err == nil {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
case http.MethodGet, http.MethodDelete, http.MethodPut:
urlquery := makeURLQuery(baseURL, path, urlArgs(args))
req, err = http.NewRequest(method, urlquery, nil)
default:
err = errors.New("wrong http method")
}
if err != nil {
return nil, err
}

// 所有请求在Header中带上jwt
req.Header.Set("Authorization", "Bearer "+pfc.GetJWT())
// 发送http请求
resp, err2 := pfc.httpClient().Do(req)
cost := util.NowTs() - startTimestamp
pfc.stat.Add(baseURL+"/"+path, cost)
return resp, err2
}

调用的例子

// getHistory 获取历史聊天记录
func (pfc *pfclientdef) getHistory(req *pfproto.PfGetHistoryReq) *pfproto.PfGetHistoryAck {
// fmt.Sprint(pfc.GetJWT())
jsonmap, err := pfc.request(ServiceCProxy2api, "archive/history", http.MethodGet, Args{
// "client_id": "s1:default",
"game_id": pfc.GameID,
"server_id": strconv.Itoa(int(req.ServerID)),
// "character_id": strconv.Itoa(int(req.PlayerID)),
"room_id": req.RoomId, //"mapzone_" + strconv.Itoa(13610004),
"start_time": strconv.Itoa(int(req.StartTime)),
"end_time": strconv.Itoa(int(req.EndTime)),
"page_size": strconv.Itoa(int(req.PageSize)),
"page_number": strconv.Itoa(int(req.PageNumber)),
})

ack := new(pfproto.PfGetHistoryAck)
if err != nil {
ack.PfErr = err.Error()
} else {
totalCount, err := jsonmap["total_count"].(json.Number).Int64()
if err != nil {
ack.PfErr = fmt.Sprintf("archive/history failed: can not get totalCount %v", err.Error())
} else {
ack.TotalCount = totalCount
}
postList, ok := jsonmap["histories"]
if !ok {
ack.PfErr = fmt.Sprintf("archive/history failed: can not get postList %v", postList)
} else {
var PostList []*pfproto.PfChatPost
for _, post0 := range postList.([]interface{}) {
jsonPost := post0.(map[string]interface{})
postId, _ := jsonPost["id"].(json.Number).Int64()
timestamp, _ := jsonPost["timestamp"].(json.Number).Int64()
post := &pfproto.PfChatPost{
Id: postId,
Body: jsonPost["body"].(string),
To: jsonPost["to"].(string),
Timestamp: timestamp,
}
PostList = append(PostList, post)
}
ack.PostList = PostList
}
}
return ack
}